package org.ourgrid.acceptance.util.aggregator;

import org.easymock.classextension.EasyMock;
import org.ourgrid.acceptance.util.AggregatorAcceptanceUtil;
import org.ourgrid.aggregator.AggregatorComponent;
import org.ourgrid.common.interfaces.control.AggregatorControl;
import org.ourgrid.common.interfaces.control.DiscoveryServiceControlClient;
import org.ourgrid.matchers.ControlOperationResultMatcher;

import br.edu.ufcg.lsd.commune.container.ObjectDeployment;
import br.edu.ufcg.lsd.commune.container.control.ModuleAlreadyStartedException;
import br.edu.ufcg.lsd.commune.container.logging.CommuneLogger;
import br.edu.ufcg.lsd.commune.context.ModuleContext;
import br.edu.ufcg.lsd.commune.network.xmpp.CommuneNetworkException;
import br.edu.ufcg.lsd.commune.processor.ProcessorStartException;
import br.edu.ufcg.lsd.commune.testinfra.AcceptanceTestUtil;

public class Req_602_Util extends AggregatorAcceptanceUtil{
	
	public Req_602_Util(ModuleContext context) {
		super(context);
	}

	public AggregatorComponent startAggregatorWithWorngPublicKey(String wrongPublicKey) 
		throws CommuneNetworkException, ProcessorStartException {
		
		AggregatorComponent component = createAggregatorComponent();
		return startAggregator(component, wrongPublicKey, false);
	}
	
	public AggregatorComponent startAggregator() 
		throws CommuneNetworkException, ProcessorStartException {
		
		AggregatorComponent component = createAggregatorComponent();
		return startAggregator(component, null, false);
	}
	
	public AggregatorComponent startAggregatorAgain(AggregatorComponent component)
		throws CommuneNetworkException, ProcessorStartException {
		
		return startAggregator(component, null, true);
	}
	
	private AggregatorComponent startAggregator(AggregatorComponent component, 
			String senderPublicKey, boolean isAlreadyStarted) {
		CommuneLogger newLogger = EasyMock.createMock(CommuneLogger.class);
		component.setLogger(newLogger);
		
		AggregatorControl aggregatorControl = getAggregatorControl(component);
		ObjectDeployment aggregatorOD = getAggregatorDeployment(component);
		
		DiscoveryServiceControlClient aggregatorClientMock = 
			EasyMock.createMock(DiscoveryServiceControlClient.class);
		
		if (senderPublicKey == null) {
			senderPublicKey = aggregatorOD.getDeploymentID().getPublicKey();
		}
		
		if (isAlreadyStarted) {
			aggregatorClientMock.operationSucceed(ControlOperationResultMatcher.eqType(ModuleAlreadyStartedException.class));
		} else {
			if (aggregatorOD.getDeploymentID().getPublicKey().equals(senderPublicKey)) {
				aggregatorClientMock.operationSucceed(ControlOperationResultMatcher.noError());
				newLogger.info("Aggregator has been successfully started.");
			} else {
				newLogger.warn("An unknown entity tried to start the Aggregator. " +
						"Only the local modules can perform this operation. " +
						"Unknown entity public key: [" + senderPublicKey + "].");
			}
		}
		
		EasyMock.replay(newLogger);
		EasyMock.replay(aggregatorClientMock);
		
		AcceptanceTestUtil.setExecutionContext(component, aggregatorOD, senderPublicKey);
		aggregatorControl.start(aggregatorClientMock);
		
		EasyMock.verify(aggregatorClientMock);
		EasyMock.verify(newLogger);
		
		EasyMock.reset(newLogger);
		
		return component;	}
	
}
